<template>
  <div class="key-generator">
    <h3>RSA 公私钥生成工具</h3>

    <button @click="generateKeys">🔧 生成密钥对</button>
    <button @click="saveKeys">💾 保存到本地</button>
    <button @click="loadKeys">📂 读取本地密钥</button>
    <button @click="deleteKeys">🗑️ 删除本地密钥</button>

    <div>
      <label>私钥 (Private Key - PKCS#8 PEM):</label>
      <textarea v-model="privateKey" rows="8" readonly placeholder="点击【生成】按钮生成私钥" />
    </div>

    <div>
      <label>公钥 (Public Key - SPKI PEM):</label>
      <textarea v-model="publicKey" rows="8" readonly placeholder="点击【生成】按钮生成公钥" />
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import IndexDB,{ Result } from '@/utils/IndexDB';

const privateKey = ref('');
const publicKey = ref('');

// 将 ArrayBuffer 转为 PEM 格式字符串
function arrayBufferToPem(buffer: ArrayBuffer, label: 'PUBLIC KEY' | 'PRIVATE KEY'): string {
  const bytes = new Uint8Array(buffer);
  let binary = '';
  for (let i = 0; i < bytes.byteLength; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  const base64 = btoa(binary);
  const lines = base64.match(/.{1,64}/g) || [];
  return `-----BEGIN ${label}-----\n${lines.join('\n')}\n-----END ${label}-----`;
}

/**
 * 生成 RSA 密钥对（使用 Web Crypto API）
 */
const generateKeys = async () => {
  try {
    const keyPair = await crypto.subtle.generateKey(
        {
          name: 'RSA-OAEP',
          modulusLength: 2048,
          publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
          hash: 'SHA-256',
        },
        true,
        ['encrypt', 'decrypt']
    );

    // 导出公钥（SPKI 格式）
    const pubBuffer = await crypto.subtle.exportKey('spki', keyPair.publicKey);
    publicKey.value = arrayBufferToPem(pubBuffer, 'PUBLIC KEY');

    // 导出私钥（PKCS#8 格式）
    const privBuffer = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);
    privateKey.value = arrayBufferToPem(privBuffer, 'PRIVATE KEY');
    window.$message?.success('生成成功')
  } catch (error) {
    console.error('密钥生成失败:', error);
    window.$message?.error('生成失败，请检查是否在 HTTPS/localhost 环境');
  }
};

/**
 * 保存密钥到 IndexDB
 */
const saveKeys = async () => {
  if (!privateKey.value || !publicKey.value) {
    window.$message?.info('请先生成密钥');
    return;
  }
  try {
    await IndexDB.set('rsa_privateKey', privateKey.value);
    await IndexDB.set('rsa_publicKey', publicKey.value);
    window.$message?.success('密钥已保存！');
  } catch (error) {
    console.error('保存失败:', error);
    window.$message?.error('保存失败');
  }
};

/**
 * 从 IndexDB 读取密钥
 */
const loadKeys = async () => {
  try {
    const privateResult: Result = await IndexDB.get('rsa_privateKey');
    const publicResult: Result = await IndexDB.get('rsa_publicKey');

    if (privateResult.content && publicResult.content) {
      privateKey.value = privateResult.content;
      publicKey.value = publicResult.content;
      window.$message?.success('密钥加载成功！');
    }else{
      window.$message?.info('请先保存密钥');
    }
  } catch (error) {
    window.$message?.error('读取失败');
  }
};

/**
 * 从 IndexDB删除密钥
 */
const deleteKeys = async () => {
  try {
    await IndexDB.remove('rsa_privateKey');
    await IndexDB.remove('rsa_publicKey');
    window.$message?.success('密钥已删除！');
  } catch (error) {
    console.error('删除失败:', error);
    window.$message?.error('删除失败:'+error,);
  }
};
</script>

<style scoped lang="less">
.key-generator {
  padding: 20px;
  font-family: Consolas, monospace;

  button {
    margin: 0 10px 10px 0;
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    background: #1890ff;
    color: white;
    cursor: pointer;

    &:hover { background: #40a9ff; }
  }

  label {
    display: block;
    margin: 10px 0 5px;
    font-weight: bold;
  }

  textarea {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background: #f9f9f9;
    font-family: monospace;
    resize: vertical;
  }
}
</style>